/**
 * @copyright 2015 Indie Semiconductor.
 *
 * This file is proprietary to Indie Semiconductor.
 * All rights reserved. Reproduction or distribution, in whole
 * or in part, is forbidden except by express written permission
 * of Indie Semiconductor.
 *
 * @file adc_device.c
 */

#include "adc_device.h"

AdcMeasureItem_t adcMeasureItem = ADC_MEASURE_ITEM_NONE;
adc_cb_func_t adcCallback = NULL;

void ADC_Handler(void)
{
    uint16_t adcResult[2];
    if (adcMeasureItem <= ADC_MEASURE_ITEM_VLED23){
        if (adcCallback !=NULL){
            adcResult[0] = ADC_SFRS->DATA0 & 0x0FFF;
            adcResult[1] = ADC_SFRS->DATA1 & 0x0FFF;
            adcResult[0] = (adcResult[0] < adcResult[1])? 0:(adcResult[0] - adcResult[1]);
            adcCallback(adcMeasureItem, adcResult[0] );
        }
    }else{
        adcResult[0] = ADC_SFRS->DATA0 & 0x0FFF;
        adcCallback(adcMeasureItem, adcResult[0] );
    }
    ADC_SFRS->ADCIRQ.CLEAR.DATAREADY  = 1;
}

void ADC_Init(AdcMeasureItem_t item, bool syncEnable)
{
    adcMeasureItem = item;
    ADC_SFRS->CONF.ATTEN = 0;// x 1/3
    ADC_SFRS->CONF.AUTOEN = 0; 
    ADC_SFRS->CONF.SAMPCYC  = ADC_SAMPLING_CYCLE_8;
    ADC_SFRS->CONF.MODE     = ADC_MODE_SINGLE_END;
    ADC_SFRS->INSEL.GUARD = 1;
    ADC_SFRS->INSEL.SYNCENA0 = 0;
    ADC_SFRS->INSEL.SYNCENA1 = 0;
    ADC_SFRS->INSEL.SYNCENA2 = 0;
    if (item <= ADC_MEASURE_ITEM_VLED23){
        ADC_SFRS->INSEL.SEQ = ADC_SEQ_2_CHANNEL;
        ADC_SFRS->INSEL.SYNCENA0 = 1;
        ADC_SFRS->INSEL.CH0 = ADC_MEASURE_ITEM_VBUCK;
        ADC_SFRS->INSEL.CH1 = item;
    }else{
        ADC_SFRS->INSEL.SEQ = ADC_SEQ_1_CHANNEL;
        ADC_SFRS->INSEL.SYNCENA0 = item;
    }
    
}

void ADC_UnInit(AdcMeasureItem_t item)
{
    
  
}

/**
 * @brief Register a callback function to ADC interrupt handler.
 *
 * @param dev Pointer to the ADC device.
 * @param cb The callback function to be registered.
 * @return 0 for success or error code upon a failure.
 */
void ADC_RegisterIRQ(adc_cb_func_t callback)
{
    adcCallback = callback;
    ADC_SFRS->ADCIRQ.CLEAR.DATAREADY  = 1;
    ADC_SFRS->ADCIRQ.ENABLE.DATAREADY = 1;
    NVIC_EnableIRQ(ADC_IRQn);
    
}

/**
 * @brief Unregister a callback function to ADC interrupt handler.
 *
 * @param dev Pointer to the ADC device.
 * @param cb The callback function to be unregistered.
 * @return 0 for success or error code upon a failure.
 */
void ADC_UnregisterIRQ(void)
{
    adcCallback = NULL;
    ADC_SFRS->ADCIRQ.CLEAR.DATAREADY  = 1;
    ADC_SFRS->ADCIRQ.ENABLE.DATAREADY = 0;
    NVIC_DisableIRQ(ADC_IRQn);
}

void ADC_Start(void)
{
    ADC_SFRS->CNTRL.CONVERT = 1;
}

